package info.webest.media;

import info.webest.media.files.FileFilter;
import info.webest.media.files.FileManager;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Random;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

public class PlayList {

	public enum PlayMode {
		MODE_NONE, MODE_SHUFFLE, MODE_REPEAT;

		public static PlayMode fromInteger(int x) {
			switch (x) {
			case 0:
				return MODE_NONE;
			case 1:
				return MODE_SHUFFLE;
			case 2:
				return MODE_REPEAT;
			}
			return MODE_NONE;
		}

		public static int toInteger(PlayMode x) {
			switch (x) {
			case MODE_NONE:
				return 0;
			case MODE_SHUFFLE:
				return 1;
			case MODE_REPEAT:
				return 2;
			}
			return 0;
		}
	}

	final static String OPTIONS_FOLDER = "folder";
	final static String OPTIONS_PLAY_MODE = "mode";

	// private Context context;
	private SharedPreferences preferences;

	private PlayMode mode;

	public Items curItems = new Items();
	public Items selItems = new Items();

	public class Items {
		private String folder = null;
		public int itemIndex = -1;
		public ArrayList<FileItem> all = new ArrayList<FileItem>();
		public ArrayList<FileItem> directories = new ArrayList<FileItem>();
		public ArrayList<FileItem> files = new ArrayList<FileItem>();

		public void assign(Items items) {

			this.folder = items.folder;
			this.itemIndex = items.itemIndex;

			this.all.clear();
			for (FileItem item : items.all) {
				this.all.add(item);
			}

			this.directories.clear();
			for (FileItem item : items.directories) {
				this.directories.add(item);
			}

			this.files.clear();
			for (FileItem item : items.files) {
				this.files.add(item);
			}
		}
	}

	public void delete(int index) {

		// delete from general list
		curItems.all.remove(index);
		/*
		 * if (curItems.itemIndex > index) { curItems.itemIndex--; }
		 */

		if (curItems.folder.equals(selItems.folder) && selItems.all.size() > 0) {

			selItems.all.remove(index);

			// delete active file
			if (selItems.itemIndex == index) {
				selItems.itemIndex = -1;
			} else
			// delete file below active file
			if (selItems.itemIndex > index) {
				selItems.itemIndex--;
			}

		}
	}

	public void onIndexChange() {
	}

	public PlayList(Context context) {
		// this.context = context;
		preferences = PreferenceManager.getDefaultSharedPreferences(context);
		readSettings();
	}

	// CurFolder
	public String getCurFolder() {
		return curItems.folder;
	}

	public void setCurFolder(String dir) {
		curItems.folder = dir;

		curItems.all.clear();
		curItems.directories.clear();
		curItems.files.clear();

		scanCurFolder();
	}

	// SelFolder
	public String getSelFolder() {
		return selItems.folder;
	}

	public void setSelFolder(String dir) {
		selItems.folder = dir;
		writeSettings();
	}

	// Shuffle, Repeat
	public PlayMode getPlayMode() {
		return mode;
	}

	public void setPlayMode(PlayMode AMode) {
		mode = AMode;
		// *writeSettings();
		SharedPreferences.Editor editor = preferences.edit();
		editor.putInt(OPTIONS_PLAY_MODE, PlayMode.toInteger(getPlayMode()));
		editor.commit();
	}

	public boolean isShuffle() {
		return (mode == PlayMode.MODE_SHUFFLE);
	}

	public boolean isRepeat() {
		return (mode == PlayMode.MODE_REPEAT);
	}

	public boolean isSelDir() {
		// String s1 = getCurFolder();
		// String s2 = getSelFolder();
		return (getSelFolder().equals(getCurFolder()));
	}

	public int getPosition() {
		return selItems.itemIndex;
	}

	public void setPosition(int p) {

		if (selItems.all.size() < p)
			selItems.itemIndex = p;
	}

	public String getTitle() {

		int i = selItems.itemIndex;
		return (i == -1 ? "" : selItems.all.get(i).getTitle());
	}

	public String getFileName() {
		int i = selItems.itemIndex;
		return (i == -1 ? "" : selItems.all.get(i).getFileName());
	}

	public File getFile() {
		int i = selItems.itemIndex;
		return (i == -1 ? null : selItems.all.get(i).getFile());
	}

	private void scanCurFolder() {

		// String fileName;

		// get file list
		File[] items_ = new File(getCurFolder())
				.listFiles(new FileExtensionFilter());

		if (items_ == null) {
			return;
		}

		if (items_.length > 0) {
			for (File item : items_) {

				if (!isFilteredItem(item))
					continue;

				FileItem song = new FileItem();
				/*
				 * fileName = item.getName(); if
				 * (FileFilter.isAudioExt(fileName)) { song.put("songTitle",
				 * fileName.substring(0, (fileName.length() - 4))); } else {
				 * song.put("songTitle", fileName); } song.put("fileName",
				 * fileName);
				 */
				song.put("file", item);

				// Adding each song to SongList
				if (item.isDirectory()) {
					curItems.directories.add(song);
				}
				if (item.isFile()) {
					curItems.files.add(song);
				}
			}

			Collections.sort(curItems.directories, new FileComparator());
			Collections.sort(curItems.files, new FileComparator());

			for (FileItem song : curItems.directories) {
				song.childCount = FileManager.getChildCount(song.getFile());
				curItems.all.add(song);
				// System.out.println(song.get("songTitle"));
			}
			// directories.clear();

			for (FileItem song : curItems.files) {
				curItems.all.add(song);
				// System.out.println(song.get("songTitle"));
			}
			// files.clear();
		}

		if (curItems.files.size() == 0) {
			curItems.itemIndex = -1;
		} else {
			curItems.itemIndex = curItems.directories.size() - 1;
		}
	}

	public void play(File f) {
		String path2 = f.getParent();
		String fileName = f.getAbsolutePath();
		String fileFomList = null;

		setCurFolder(path2);
		selItems.assign(curItems);

		int i = 0;
		for (FileItem song : selItems.all) {
			fileFomList = song.get("file").toString();
			if (fileFomList.equals(fileName)) {
				selItems.itemIndex = i;
				break;
			}
			i++;
		}
	}

	public boolean enabled() {
		return (selItems.files.size() > 0 && selItems.itemIndex != -1);
	}

	public void previous() {

		if (!enabled())
			return;

		if (selItems.itemIndex > 0) {
			selItems.itemIndex--;
		} else {
			// play last song
			selItems.itemIndex = selItems.all.size() - 1;
		}
	}

	public void next() {

		if (!enabled())
			return;

		// check if next song is there or not
		if (selItems.itemIndex < (selItems.all.size() - 1)) {
			selItems.itemIndex++;
		} else {
			// play first song
			selItems.itemIndex = selItems.directories.size();
		}
	}

	public void autoNext() {

		if (!enabled())
			return;

		// check for repeat is ON or OFF
		if (isRepeat()) {
			// repeat is on play same song again
		} else if (isShuffle()) {
			// shuffle is on - play a random song
			Random rand = new Random();
			selItems.itemIndex = selItems.directories.size()
					+ rand.nextInt(selItems.files.size());
		} else {
			// no repeat or shuffle ON - play next song
			next();
		}
	}

	public void autoPrevious() {

		if (!enabled())
			return;

		// check for repeat is ON or OFF
		if (isRepeat()) {
			// repeat is on play same song again
		} else if (isShuffle()) {
			// shuffle is on - play a random song
			Random rand = new Random();
			selItems.itemIndex = selItems.directories.size()
					+ rand.nextInt(selItems.files.size());
		} else {
			// no repeat or shuffle ON - play previous song
			previous();
		}
	}

	private boolean isFilteredItem(File item) {

		String name = item.getName();
		boolean is_dir = item.isDirectory();
		boolean is_file = item.isFile();

		boolean is_ext = FileFilter.isImageExt(name)
				|| FileFilter.isAudioExt(name) || FileFilter.isVideoExt(name)
				|| FileFilter.isBookExt(name);

		return (is_dir || (is_file && is_ext));
	}

	class FileExtensionFilter implements FilenameFilter {

		public boolean accept(File item, String name) {

			boolean is_dir = item.isDirectory();
			boolean is_file = item.isFile();
			boolean is_ext = FileFilter.isImageExt(name)
					|| FileFilter.isAudioExt(name)
					|| FileFilter.isVideoExt(name)
					|| FileFilter.isBookExt(name);

			return (is_dir || (is_file && is_ext));
			// return is_ext;
		}
	}

	private class FileComparator implements Comparator<HashMap<String, Object>> {
		@SuppressLint("DefaultLocale")
		@Override
		public int compare(HashMap<String, Object> o1,
				HashMap<String, Object> o2) {
			return ((FileItem) o1).getTitle().toLowerCase()
					.compareTo(((FileItem) o2).getTitle().toLowerCase());
		}
	}

	/*
	 * private class StrComparator implements Comparator<String>{
	 * 
	 * @SuppressLint("DefaultLocale") @Override public int compare(String s1,
	 * String s2) { return s1.toLowerCase().compareTo(s2.toLowerCase()); } }
	 */

	public void writeSettings() {
		SharedPreferences.Editor editor = preferences.edit();
		// editor.putInt("timeSave", time);
		// String s = getSelFolder();
		editor.putString(OPTIONS_FOLDER, getSelFolder());
		editor.commit();
	}

	private void readSettings() {
		// "time" parameter program reads in another method
		// String s = preferences.getString(OPTIONS_FOLDER, "/");
		setSelFolder(preferences.getString(OPTIONS_FOLDER, "/"));
		setCurFolder(getSelFolder());
		// nowPlayer = preferences.getInt("nowPlayerSave", -1);

		int savedMode = preferences.getInt(OPTIONS_PLAY_MODE,
				PlayMode.toInteger(PlayMode.MODE_NONE));
		setPlayMode(PlayMode.fromInteger(savedMode));
	}

}
